#ifndef VBLANKVIEW_H
#define VBLANKVIEW_H

class VBlank;
class VAbstractControl;

class VAbstractBlankRender
{
public:
	VAbstractBlankRender() {}
	virtual ~VAbstractBlankRender() {}

public:
	virtual void update(const VBlank* blank) = 0;
};

//////////////////////////////////////////////////////////////////////////
// VTestBlockUserData
class VControlBlockUserData: public QTextBlockUserData
{
public:
	VControlBlockUserData(VAbstractControl* control): m_control(control) {}
	
public:
	void setControl(VAbstractControl* control) { m_control = control; }
	VAbstractControl* control() const { return m_control; }

private:
	VAbstractControl* m_control;
};

//////////////////////////////////////////////////////////////////////////
// VBlankEditor
class VBlankEditor: public QTextEdit
{
	Q_OBJECT

public:
	VBlankEditor(QWidget* parent=0);

public:
	void updateUserData();

public:
	void selectBlock(const QTextBlock& block);
	int updateCurentBlockIdx();

public slots:
		void canEditBlock(bool canEdit);

protected:
	virtual void keyPressEvent(QKeyEvent *e);

private:
	QTextBlock nextSelectedBlock();

private:
	QList<VControlBlockUserData*> m_userData;
	int m_curBlockIdx;
};

//////////////////////////////////////////////////////////////////////////
// VBlankView
class VBlankView : public QObject, public VAbstractBlankRender
{
	Q_OBJECT

public:
	VBlankView(QWidget *parent);
	~VBlankView();

public:
	QWidget* widget() const { return m_bkgWidget; }
	void update(const VBlank* blank);

private:
	typedef QVector<QTextLength> TableConst;
	QList<TableConst> calcTablesConstrains(const VBlank* blank);

private slots:
	void cursorPositionChange();
	void currentCharFormatChange(const QTextCharFormat& f);

signals:
	void controlClicked(VAbstractControl* control);
	void canEditedBlock(bool canEdited);	

private:
	VBlankEditor* m_blankEditor;
	QList<VAbstractControl*> m_stackControls;

private:
	QWidget* m_bkgWidget;
	
};

//////////////////////////////////////////////////////////////////////////
// VPropertyBrowserHelper
class QtProperty;
class QtVariantProperty;
class QtVariantPropertyManager;
class QtTreePropertyBrowser;

class VPropertyBrowserHelper: public QObject
{
	Q_OBJECT

public:
	VPropertyBrowserHelper(QObject* parent=0);
	~VPropertyBrowserHelper();

private:
	void updateExpandState();
	void addProperty(QtVariantProperty *property, const QString &id);

	public slots:
		void controlClick(VAbstractControl* control);

		private slots:
			void valueChanged(QtProperty *property, const QVariant &value);

signals:
			void scriptChanged();

private:
	QtTreePropertyBrowser* m_propEditor;
	QtVariantPropertyManager* m_variantManager;
	QMap<QtProperty*, QString> propertyToId;
	QMap<QString, QtVariantProperty*> idToProperty;
	QMap<QString, bool> idToExpanded;

	VAbstractControl* m_curControl;
};

//////////////////////////////////////////////////////////////////////////
// VObjectInspector
class VObjectInspector: public QObject
{
	Q_OBJECT

public:
	VObjectInspector(QWidget* parent=0);
	~VObjectInspector();

public:
	virtual QWidget* widget() const { return m_objInspDoc; }

public:
	VPropertyBrowserHelper* propertyBrowser() const { return m_propHelper; }

private:
	QDockWidget* m_objInspDoc;
	QTabWidget* m_objInspTab;
	VPropertyBrowserHelper* m_propHelper;
};

//////////////////////////////////////////////////////////////////////////
// VBlankWidgetView
class VFlowLayout;
class VPageLayout;

class VScrollAreaHelper: public QScrollArea
{
	Q_OBJECT

public:
	VScrollAreaHelper(QWidget* parent=0):QScrollArea(parent) {}

protected:
	virtual void focusInEvent(QFocusEvent *e)
	{
		qDebug() << "focus in";
		QScrollArea::focusInEvent(e);
	}

	virtual void focusOutEvent(QFocusEvent* e)
	{
		qDebug() << "focus out";
		QScrollArea::focusOutEvent(e);
	}

	virtual void keyPressEvent(QKeyEvent* event)
	{
		qDebug() << event->key();
		QScrollArea::keyPressEvent(event);
	}
};

class KeyPressEater : public QObject
{
	Q_OBJECT

public:
		KeyPressEater(QObject* parent=0)
			: QObject(parent)
			, m_firstWidget(0)
			, m_lastWidget(0)
		{}

public:
	void setFirstLastFocusWidget(QWidget* first, QWidget* last)
	{
		m_firstWidget = first;
		m_lastWidget = last;

		qDebug() << m_firstWidget << m_lastWidget;
	}

protected:
	bool eventFilter(QObject *obj, QEvent *event)
	{
		qDebug() << obj << event;
		/*if (event->type() == QEvent::KeyRelease) {
			QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
			qDebug() << "################";
			qDebug("Ate key press %d", keyEvent->key());
			qDebug() << obj;
			return true;
		} else {
			// standard event processing
			return QObject::eventFilter(obj, event);
		}*/
		QKeyEvent* ke = dynamic_cast<QKeyEvent*>(event);
		if (ke && ke->key() == Qt::Key_Tab)
		{
			QWidget* w = qobject_cast<QWidget*>(obj);
			//qDebug() << w->nextInFocusChain();
			//if (w && w->focusWidget() == m_lastWidget)
			//	m_firstWidget->setFocus();
			//QCoreApplication::sendEvent( obj, new QFocusEvent( QEvent::FocusOut, Qt::TabFocusReason ) );
			return true;
		}

		return QObject::eventFilter(obj, event);
	}

private:
	QWidget* m_firstWidget;
	QWidget* m_lastWidget;
};

class VScrollWidgetContent: public QWidget
{
	Q_OBJECT

public:
	VScrollWidgetContent(QWidget* parent=0):QWidget(parent) 
	{
		m_keyPressEater = new KeyPressEater;
		installEventFilter(m_keyPressEater);
	}

protected:
	virtual void focusInEvent(QFocusEvent *e)
	{
		qDebug() << "focus in";
		QWidget::focusInEvent(e);
	}

	virtual void focusOutEvent(QFocusEvent* e)
	{
		qDebug() << "focus out";
		QWidget::focusOutEvent(e);
	}

	virtual void keyPressEvent(QKeyEvent* event)
	{
		qDebug() << event->key();
		QWidget::keyPressEvent(event);
	}

private:
	KeyPressEater* m_keyPressEater;
};

class VBlankWidgetView: public QObject, public VAbstractBlankRender
{
	Q_OBJECT

public:
	VBlankWidgetView(bool hasObjectInspector=false, QWidget *parent=0);
	~VBlankWidgetView();

public:
	QWidget* widget() const { return m_scrollArea; }
	virtual void update(const VBlank* blank);
	QWidget* printWidget() const { return m_scrollAreaWidgetContents; }

private slots:
	void focusChange(QWidget* old, QWidget* now);

private:
	//QWidget* m_bkgWidget;
	QWidget* m_scrollAreaWidgetContents;
	VScrollAreaHelper* m_scrollArea;
	VPageLayout* m_mainLayout;
	QWidget* m_firstChild;
	VObjectInspector* m_objInspector;
	bool m_hasObjectInspector;
	VAbstractControl* m_curControl;
	KeyPressEater* m_keyPressEater;

	QMap<QWidget*, VAbstractControl*> m_focusWidgets;
	QList<VAbstractControl*> m_absControls;
};

#endif // VBLANKVIEW_H
